package dieciLuglio;

import java.io.*;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.sql.*;
import java.util.*;
import java.net.*;

import javax.crypto.Cipher;

public class ServerThread extends Thread{

	private static Statement stat;
	BufferedReader in=null; 
	private static Connection conn;
	private Socket socket;
	private static int importoDaPagare;
	private static Utente s;
	private static GregorianCalendar data=new GregorianCalendar();
	private static int idTavolo;
	private static InputStream keyReceive;
	private static OutputStream keySend;
	private Key keyDES;
	PrintWriter out=null;
	
	
	

	public ServerThread(Socket s) throws Exception{
		socket=s;
		InputStreamReader isr = new InputStreamReader(socket.getInputStream());
		in = new BufferedReader(isr);
		
		keyReceive=socket.getInputStream();
		keySend=socket.getOutputStream();
		
		OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
		BufferedWriter bw = new BufferedWriter(osw);
		
		out = new PrintWriter(bw,true);
		
		//Creazione chiave DES da utilizzare per codifica e decofica dei dati 
		keyDES=DES.generaChiave();
		
		
		scambioChiavi();		
		
		start();
	}
	
	public void scambioChiavi() throws Exception{
		
		//Ricezione e rigenerazione chiave pubblica RSA con la quale criptare la chiave DES da mandare ad Inviatore
		byte[] publicKeyByte=new byte[1000];
		int numByte=keyReceive.read(publicKeyByte);
		publicKeyByte=Arrays.copyOf(publicKeyByte, numByte);
		X509EncodedKeySpec key=new X509EncodedKeySpec(publicKeyByte);
		KeyFactory keyF=KeyFactory.getInstance("RSA");
		
		//Chiave Pubblica RSA generata
		PublicKey keyP=keyF.generatePublic(key);
		Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
		
		//inizializzazione cifrario alla cifratura tramite chiave pubblica RSA
		cipher.init(Cipher.ENCRYPT_MODE, keyP);
		
		//Cifratura ed invio della chiave DES ad Inviatore
		byte[]chiaveDES=keyDES.getEncoded();
		byte[]chiaveDESCriptata=cipher.doFinal(chiaveDES);
		keySend.write(chiaveDESCriptata);
	}

	public void run(){
		String str;
		try{
			while(true){
				
				str = in.readLine();
				if(str != null){
					str=DES.decripta(str, keyDES);
				
					System.out.println("AZIONE LETTA :"+str);
					String supporto=str;
					
					
					StringTokenizer stk=new StringTokenizer(str);
					String metodo=stk.nextToken();
					
					

					if(metodo.equals("datiPiatti")){
						LinkedList<Alimento> ll=datiPiatti(stk.nextToken());
						int lunghezza=ll.size();
						String list=""+lunghezza+" ";
						Iterator<Alimento> it=ll.iterator();
						while(it.hasNext()){
							list=list+it.next().getCodice()+" ";
						}
						list=DES.cripta(list, keyDES);
						out.println(list);
						
					}
					
					else if(metodo.equals("chiudi")){
						break;
					}
					else if(metodo.equals("creaAlimento")){
						int valore=Integer.parseInt(stk.nextToken());
						Alimento a=(Alimento)creaAlimento(valore);
						String alim=a.toString();
						alim=DES.cripta(alim, keyDES);
						out.println(alim);
						break;
					}
					else if(metodo.equals("creaAlimentos")){
						String nome=str.substring(14);
						Alimento a=(Alimento)creaAlimento(nome);
						String alim=a.toString();
						alim=DES.cripta(alim, keyDES);
						out.println(alim);
						break;
					}
					else if (metodo.equals("accendiTavolo")){
						int codiceTav=Integer.parseInt(stk.nextToken());
						boolean eseguito=accendiTavolo(codiceTav);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if (metodo.equals("spegniTavolo")){
						int codiceTav=Integer.parseInt(stk.nextToken());
						boolean eseguito=spegniTavolo(codiceTav);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("inviaOrdine")){
						int idTavolo=Integer.parseInt(stk.nextToken());
						int lunghezza=Integer.parseInt(stk.nextToken());
						String lista=" ";
						for(int i=0;i<lunghezza;i++){
							lista+=stk.nextToken()+" ";
						}
						boolean eseguito=inviaOrdine(idTavolo,lunghezza,lista);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("valuta")){
						int codice=Integer.parseInt(stk.nextToken());
						int voto=Integer.parseInt(stk.nextToken());
						boolean eseguito=valuta(codice,voto);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("getValoriValutazione")){
						int codice=Integer.parseInt(stk.nextToken());
						double [] d=getValoriValutazione(codice);
						String s=d[0]+" "+d[1];
						s=DES.cripta(s, keyDES);
						out.println(s);
					}
					
		
					
					else if(metodo.equals("CostruisciMenu")){
						String nomeMenu=stk.nextToken();				
						LinkedList<Alimento> ll=CostruisciMenu(nomeMenu);
						int lunghezza=ll.size();
						String list=""+lunghezza+" ";
						Iterator<Alimento> it=ll.iterator();
						while(it.hasNext()){
							list=list+it.next().getCodice()+" ";
						}
						list=DES.cripta(list, keyDES);
						out.println(list);
					}
					else if(metodo.equals("RandomMenu")){		
						LinkedList<Alimento> ll=RandomMenu();
						int lunghezza=ll.size();
						String list=""+lunghezza+" ";
						Iterator<Alimento> it=ll.iterator();
						while(it.hasNext()){
							list=list+it.next().getCodice()+" ";
						}
						list=DES.cripta(list, keyDES);
						out.println(list);
					}
					
					
					
					
					
					else if(metodo.equals("contaPiatto")){	
						String piatto=stk.nextToken();
						String l=Integer.toString(contaPiatto(piatto));
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("contaQuantiMenu")){	
						String l=Integer.toString(contaQuantiMenu());
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("getNumeroPosti")){	
						int idTavolo=Integer.parseInt(stk.nextToken());
						String l=Integer.toString(getNumeroPosti(idTavolo));
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("getImportoDaPagare")){	
						int idTavolo=Integer.parseInt(stk.nextToken());
						String l=Double.toString(getImportoDaPagare(idTavolo));
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("getCodiceU")){	
						String nick=stk.nextToken();
						String l=Integer.toString(getCodiceU(nick));
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("dissociaUtenteTavolo")){	
						int idTavolo=Integer.parseInt(stk.nextToken());
						boolean eseguito=dissociaUtenteTavolo(idTavolo);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("associaUtenteATavolo")){	
						String nick=stk.nextToken();
						int idTavolo=Integer.parseInt(stk.nextToken());
						boolean eseguito=associaUtenteATavolo(nick,idTavolo);
						String l=boolToString(eseguito);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					else if(metodo.equals("getIdUtenteTavolo")){
						int idTavolo=Integer.parseInt(stk.nextToken());
						int l=getIdUtenteTavolo(idTavolo);
						String a=String.valueOf(l);
						a=DES.cripta(a, keyDES);
						out.println(a);
					}
					else if(metodo.equals("getUtenteTavolo")){
						int idTavolo=Integer.parseInt(stk.nextToken());
						Utente q=(Utente)getUtenteTavolo(idTavolo);
						String l=q.toString();
						l=DES.cripta(l, keyDES);
						out.println(l);
					}




					else if(metodo.equals("creaMenu")){
						int codice=Integer.parseInt(stk.nextToken());
						Menu m=(Menu)creaMenu(codice);
						String l=m.toString();
						l=DES.cripta(l, keyDES);
						out.println(l);
					}



					else if(metodo.equals("creaUtente")){
						String nome=stk.nextToken();
						String pass=stk.nextToken();
						Utente u=(Utente)creaUtente(nome,pass);
						String l=u.toString();
						l=DES.cripta(l, keyDES);
						out.println(l);
						//break;
					}
					else if(metodo.equals("creaUtenteID")){
						int codice=Integer.parseInt(stk.nextToken());
						Utente u=(Utente)creaUtente(codice);
						String l=DES.cripta(u.toString(), keyDES);
						out.println(l);
						//break;
					}
					
					else if(metodo.equals("utenteGiaRegistrato")){
						String ute=stk.nextToken();
						String s=boolToString(utenteGiaRegistrato(ute));
						s=DES.cripta(s, keyDES);
						out.println(s);
						//break;
					}
					else if(metodo.equals("registraUtente")){
						String ute=stk.nextToken();
						String s=boolToString(registraUtente(ute));
						s=DES.cripta(s, keyDES);
						out.println(s);
						//break;
					}
					else if(metodo.equals("accediUtente")){
						String nick=stk.nextToken();
						String pass=stk.nextToken();
						String s=boolToString(accediUtente(nick,pass));
						s=DES.cripta(s, keyDES);
						out.println(s);
						//break;
					}
					
					
					else if(metodo.equals("aggiornaOrdine")){
						String r=aggiornaOrdine();
						r=DES.cripta(r, keyDES);
						out.println(r);
					}
					else if(metodo.equals("evadiOrdine")){
						int idTavolo=Integer.parseInt(stk.nextToken());
						String r=evadiOrdine(idTavolo);
						r=DES.cripta(r, keyDES);
						out.println(r);
					}
					
					else if(metodo.equals("quantiTavoli")){
						String s=quantiTavoli();
						s=DES.cripta(s, keyDES);
						out.println(s);
					}
					else if(metodo.equals("getRecensioni")){
						int codicePiatto=Integer.parseInt(stk.nextToken());
						String s=getRecensioni(codicePiatto);
						s=DES.cripta(s, keyDES);
						out.println(s);
					}
					else if(metodo.equals("scriviRecensione")){
						String g=supporto.substring(17,supporto.length());
						StringTokenizer m=new StringTokenizer(g,"#");
						int voto=Integer.parseInt(m.nextToken());
						String rec=m.nextToken();
						String data=m.nextToken();
						int idPiatto=Integer.parseInt(m.nextToken());
						String nome=m.nextToken();
						boolean h=scriviRecensione(voto,rec,data,idPiatto,nome);
						String l=boolToString(h);
						l=DES.cripta(l, keyDES);
						out.println(l);
					}
					
					else{
						System.out.print("PORCA MISERIA");
					}

				}
				else{
					System.out.println("Azione: null");
					break;
				}
			}		
		}catch(IOException e){
			e.printStackTrace();
		}
		try{
			out.close();
			in.close();
			ServerRisto.threadAttivi--;
			socket.close();
			System.out.println("Chiusura ServerThread "+socket);
		}catch(IOException e){
			e.printStackTrace();
		}

	}
	
	public boolean scriviRecensione(int voto,String rec,String data,int idPiatto,String nome){
		String inserisciRE="insert into Valutazione (voto,commento,data,codiceP,nomeCliente) values("+voto+",'"+rec+"','"+data+"',"+idPiatto+",'"+nome+"')";
		boolean esito=false;
		try {
			conn= getConnection();
			stat=conn.createStatement(); 
			stat.executeUpdate(inserisciRE);
			esito=true;
		} catch (SQLException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		return esito;
	}	
	
	
	public String getRecensioni(int idPiatto){
		String ritorno="|";
		
		try{
			conn= getConnection();
			stat=conn.createStatement(); 
			
			String q="select voto,commento, nomeCliente from Valutazione where codiceP="+idPiatto;
			ResultSet rs= stat.executeQuery(q);
			while(rs.next()){
				int v=rs.getInt(1);
				String tmpComm=rs.getString(2);
				String tmpNom=rs.getString(3);
				
				String re;
				String nom;
				
				if(tmpComm==null){
					re="Nessuna recensione";
				}
				else{
					re=tmpComm;
				}
				if(tmpNom==null || tmpNom.equals("         ") || tmpNom.equals("") ){
					nom="Anonimo";
				}
				else{
					nom=tmpNom;
				}
				Recensione r=new Recensione(re,nom,v);
				ritorno+=r.toString()+"|";
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		catch(IOException e){
			e.printStackTrace();
		}
		return ritorno;
	}
	
	private String quantiTavoli() {
		String query="select idTavolo from Tavolo order by idTavolo desc limit 1";
		int quanti=0;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			ResultSet rs = stat.executeQuery(query);
			while(rs.next()){
				quanti=rs.getInt(1);
			}
		}catch(SQLException s){
			s.printStackTrace();
			System.out.println("problema con il database");
		} catch (IOException e) {
			e.printStackTrace();
		}

		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		quanti++;
		String ritorno=String.valueOf(quanti);
		return ritorno;
	}

	private String boolToString(boolean e){
		String l="";
		if (e)
			l="vero";
		else
			l="falso";
		return l;
	}



	public static Menu creaMenu(int codice){
		Menu m=new Menu();
		try{
			conn = getConnection();
			stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("Select * from Menu where codice="+codice);
			while(rs.next()){
				m.setCodice(codice);
				m.setNome(rs.getString(4));
				m.setDescrizione(rs.getString(3));
				m.setTipo(rs.getString(2));
			}
		}catch(SQLException s){
			s.printStackTrace();
			System.out.println("problema con il database");

		} catch (IOException e) {
			e.printStackTrace();
		}

		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		riempiLista(codice,m);

		return m;
	}

	private static void riempiLista(int codice,Menu m){
		LinkedList<Alimento>lista=new LinkedList<Alimento>();
		try{
			conn = getConnection();
			stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select codice from Piatto as p , MenuPiatto as m where p.codice=m.codiceP and m.codiceM="+codice);
			while(rs.next()){
				lista.add(creaAlimento(rs.getInt(1)));
			}
		}catch(SQLException s){
			s.printStackTrace();
		}
		catch(IOException e){
			e.printStackTrace();
		}
		m.setPiattiMenu(lista);
	}



	public static LinkedList<Alimento> datiPiatti(String tipoPiatto){
		LinkedList<Alimento> lista=new LinkedList<Alimento>();
		String cosaContare="select * from Piatto where tipo='"+tipoPiatto+"'";

		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(cosaContare);
			while(rs.next()){
				Alimento a=creaAlimento(rs.getInt(1));
				lista.add(a);
			}	
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException v){
			v.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return lista;

	}

	public static Alimento creaAlimento(int codice){
		Alimento s=new Alimento();

		try{		
			conn = getConnection();
			stat = conn.createStatement();

			ResultSet rs = stat.executeQuery("SELECT * FROM Piatto where codice='"+codice+"'");
			while(rs.next()){
				s.setDescrizione(rs.getString(2));
				s.setNome(rs.getString(3));
				s.setTipoPiatto(rs.getString(4));
				s.setPrezzo(rs.getDouble(5));
				s.setValutazioneMedia(rs.getDouble(6));
				s.setNumeroValutazioni(rs.getInt(7));
				s.setCodificaPiatto(rs.getInt(8));
				s.setCodice(codice);
				s.setFoto(rs.getString(9));
			}
			//riempiListaIngredienti(codice);
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return s;
	}

	public static Alimento creaAlimento(String nome){
		Alimento s=new Alimento();

		try{		
			conn = getConnection();
			stat = conn.createStatement();

			ResultSet rs = stat.executeQuery("SELECT * FROM Piatto where nome='"+nome+"'");
			while(rs.next()){
				s.setCodice(rs.getInt(1));
				s.setDescrizione(rs.getString(2));
				s.setNome(rs.getString(3));
				s.setTipoPiatto(rs.getString(4));
				s.setPrezzo(rs.getDouble(5));
				s.setValutazioneMedia(rs.getDouble(6));
				s.setNumeroValutazioni(rs.getInt(7));
				s.setCodificaPiatto(rs.getInt(8));
				s.setFoto(rs.getString(9));
			}
			//riempiListaIngredienti(codice);
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return s;
	}

	public static boolean accendiTavolo(int i){
		s=creaUtente(1);
		boolean eseguito=false;
		String accendiTavolo="update Tavolo set statoPC='ON' where idTavolo="+i;
		try{		
			conn = getConnection();
			stat = conn.createStatement();
			stat.executeUpdate(accendiTavolo);
			eseguito=true;
		}catch(SQLException s){
			s.printStackTrace();
			System.out.println("problema con il database");
		}catch(IOException e){
			e.printStackTrace();
			System.out.println("problema accendi tavolo"); 
		}
		finally{
			try{
				conn.close();
				stat.close();
			}catch(SQLException e){
				System.out.println("Errore chiusura");
			}
		}	
		return eseguito;
	}

	public static boolean spegniTavolo(int q){
		String spegniTavolo="update Tavolo set statoPC='OFF' where idTavolo="+q;
		String scollegaUtente="update TavoloUtente set codiceU=1 where idTavolo="+q;
		boolean eseguito=false;
		try {
			conn = getConnection();
			stat = conn.createStatement();

			stat.executeUpdate(spegniTavolo);
			stat.executeUpdate(scollegaUtente);
			eseguito=true;
		} catch (SQLException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return eseguito;
	}

	protected static String getData(){
		int giorno=data.get(GregorianCalendar.DAY_OF_MONTH);
		int mese=data.get(GregorianCalendar.MONTH)+1;
		int anno=data.get(GregorianCalendar.YEAR);
		String d;
		if(giorno<10 && mese<10){
			d=anno+"-0"+mese+"-0"+giorno;
		}
		else if(giorno<10 && mese>=10){
			d=anno+"-"+mese+"-0"+giorno;
		}
		else if(giorno>=10 && mese<10){
			d=anno+"-0"+mese+"-"+giorno;
		}
		else{
			d=anno+"-"+mese+"-"+giorno;
		}
		return d;
	}





	public static boolean inviaOrdine(int idTavolo,int lunghezza,String lista){
		StringTokenizer st=new StringTokenizer(lista);
		
		importoDaPagare=0;
		String data=getData();
		boolean eseguito=false;
		boolean eseguito1=false;
		Ordinazione ord=new Ordinazione(idTavolo,data);
		
		for(int i=0;i<lunghezza;i++){
			int codice=Integer.parseInt(st.nextToken());
			Alimento a=creaAlimento(codice);
			importoDaPagare+=a.getPrezzo();
			String InserisciOrdiPiatti="insert into OrdinazionePiatto values("+ord.getCodiceOrdinazione()+","+a.getCodice()+")";
			try {
				conn = getConnection();
				stat = conn.createStatement();
				stat.executeUpdate(InserisciOrdiPiatti);
				eseguito=true;
			} catch (SQLException e) {
				eseguito=false;
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		String inserisciImporto="update Ordinazione set Importo='"+importoDaPagare+"' , Pagato='N' where codice='"+ord.getCodiceOrdinazione()+"'";
		try {
			conn = getConnection();
			stat = conn.createStatement();
			stat.executeUpdate(inserisciImporto);
			eseguito1=true;
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try{
				stat.close();
				conn.close();
			}catch(SQLException w){
				w.printStackTrace();
			}
		}
		return eseguito&&eseguito1;
	}


	public static boolean valuta(int codice,int voto){
		boolean eseguito=false;
		double [] v=getValoriValutazione(codice);
		double media=(v[0]*v[1]+voto)/(v[1]+1);
		String aggiornaPiatto="update Piatto set valutazioneMedia='"+media+"' , numeroVotazione='"+(v[1]+1)+"' where codice='"+codice+"'";
		try{
			conn = getConnection();
			stat = conn.createStatement();
			stat.executeUpdate(aggiornaPiatto);
			eseguito=true;
		}catch(SQLException e){
			e.printStackTrace();
			eseguito=false;
		}catch(IOException e){
			e.printStackTrace();
			eseguito=false;
		}
		finally{
			try{
				stat.close();
				conn.close();
			}catch(SQLException w){
				w.printStackTrace();
			}
		}
		return eseguito;
	}

	public static double [] getValoriValutazione(int codice){
		double[] val=new double[2];
		ResultSet r=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			r=stat.executeQuery("select valutazioneMedia, numeroVotazione from Piatto where codice='"+codice+"'");
			while(r.next()){
				val[0]=r.getDouble(1);
				val[1]=r.getDouble(2);
			}

		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try{
				r.close();
				stat.close();
				conn.close();
			}catch(SQLException w){
				w.printStackTrace();
			}
		}
		return val;	
	}

	public static LinkedList<Alimento> CostruisciMenu(String nomeMenu){
		ResultSet rs=null;
		LinkedList<Alimento> lista=new LinkedList<Alimento>();
		try{
			conn = getConnection();
			stat = conn.createStatement();
			String trovaAlimenti="select codiceP from MenuPiatto as m, Menu as i where i.nome='"+nomeMenu+"' and m.codiceM=i.codice";
			rs=stat.executeQuery(trovaAlimenti);
			while(rs.next()){
				lista.add(creaAlimento(rs.getInt(1)));
			}
		}catch(SQLException f){
			f.printStackTrace();
		}catch(IOException n){
			n.printStackTrace();
		}
		finally{
			try{
				stat.close();
				conn.close();
				rs.close();
			}catch(SQLException d){
				d.printStackTrace();
			}
		}
		return lista;
	}

	public static LinkedList<Alimento> RandomMenu(){
		LinkedList<Alimento> [] menu=new LinkedList[3];
		LinkedList<Alimento> rest=new LinkedList<Alimento>();
		ResultSet rs=null;

		//CREAZIONE DELLE LINKEDLIST
		for(int i=0;i<menu.length;i++){
			menu[i]=new LinkedList<Alimento>();
		}

		//RIEMPIMENTO DELLE LINKEDLIST CON I MIGLIORI 5 PIATTI DI OGNI PORTATA
		for(int i=0;i<menu.length;i++){
			String selezionaMenu="Select codice from Piatto where codificaTipo='"+(i+1)+"' ORDER BY valutazioneMedia DESC LIMIT 5";
			try{
				conn = getConnection();
				stat = conn.createStatement();	
				rs=stat.executeQuery(selezionaMenu);
				while(rs.next()){
					menu[i].add(creaAlimento(rs.getInt(1)));
				}
			}catch(SQLException c){
				c.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			finally{
				try{
					stat.close();
					conn.close();
					rs.close();
				}catch(SQLException d){
					d.printStackTrace();
				}
			}
		}
		//SELEZIONE DI UNO TRA I MIGLIORI 5 IN MANIERA RANDOM
		for(int i=0;i<menu.length;i++){
			Random r=new Random();
			int casuale=r.nextInt(menu.length);
			rest.add(menu[i].get(casuale));
		}
		return rest;
	}

	public static int contaPiatto(String tipoPiatto){
		ResultSet rs=null;
		int contatore=0;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			String cosaContare="select * from Piatto where tipo='"+tipoPiatto+"'";
			rs=stat.executeQuery(cosaContare);
			while(rs.next()){
				contatore++;
			}
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException ee){
			ee.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return contatore;
	}

	public static int contaQuantiMenu(){
		int cont=0;
		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			String conta="select tipo from Menu";
			rs=stat.executeQuery(conta);
			while(rs.next())
				cont++;
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return cont;
	}

	public static int getNumeroPosti (int e){
		int p=0;
		String a="select numeroPosti from Tavolo where idTavolo="+e;
		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(a);
			while(rs.next()){
				p=rs.getInt(1);
			}	
		}catch(SQLException eq){
			eq.printStackTrace();
		}catch(IOException d){
			d.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException ew){
				ew.printStackTrace();
			}
		}
		return p;
	}

	public static double getImportoDaPagare(int idTavolo){
		double imp=0;
		char c='u';
		String quantoPagano="select Importo, Pagato from Ordinazione where idTavolo='"+idTavolo+"' order by codice desc limit 1";
		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(quantoPagano);
			while(rs.next()){
				imp=rs.getDouble(1);
				c=rs.getString(2).charAt(0);
			}
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException w){
			w.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException ew){
				ew.printStackTrace();
			}
		}
		if(c=='S'){
			imp=0;
		}
		return imp;
	}

	public static int getCodiceU(String nick){
		String ut="select codiceU from Utenti where nick='"+nick+"'";
		int c=0;
		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(ut);
			while(rs.next())
				c=rs.getInt(1);
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException w){
			w.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
				rs.close();
			}catch(SQLException ew){
				ew.printStackTrace();
			}
		}
		return c;
	}

	public static boolean dissociaUtenteTavolo(int c){
		boolean eseguito=false;
		String scollegaUtente="update TavoloUtente set codiceU=1 where idTavolo="+c;
		try {
			conn = getConnection();
			stat = conn.createStatement();
			stat.executeUpdate(scollegaUtente);
			eseguito=true;
		} catch (SQLException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try {
				stat.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} 
		return eseguito;
	}

	public static boolean associaUtenteATavolo(String nick,int idTavolo){
		boolean eseguito=false;
		Utente s1=creaUtente(nick,"");
		int c=getCodiceU(nick);
		String f="update TavoloUtente set codiceU="+c+" where idTavolo="+idTavolo;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			stat.executeUpdate(f);
			eseguito=true;
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException w){
			w.printStackTrace();
		}
		finally{
			try{
				conn.close();
				stat.close();
			}catch(SQLException ew){
				ew.printStackTrace();
			}
		}
		return eseguito;
	}

	public static int getIdUtenteTavolo(int idTavolo){
		String ut="select codiceU  from TavoloUtente where idTavolo="+idTavolo;
		int c=0;
		ResultSet rs=null;
		try {
			conn = getConnection();
			stat = conn.createStatement();
			rs = stat.executeQuery(ut);
			while(rs.next())
				c=rs.getInt(1);	
		} catch (SQLException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return c;
	}
	public static Utente creaUtente(int idUtente){
		Utente ritorno=new Utente();
		ritorno.setCodice(idUtente);
		String completaUtente="select * from Utenti where codiceU="+idUtente;
		ResultSet rs=null;
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(completaUtente);
			while(rs.next()){
				ritorno.setNome(rs.getString(2));
				ritorno.setCognome(rs.getString(3));
				//this.dataDiNascita=rs.getDate(4);
				ritorno.setIndirizo(rs.getString(5));
				ritorno.setNick(rs.getString(6));
				ritorno.setPass(rs.getString(7));
			}
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException ew){
			ew.printStackTrace();
		}
		finally{
			try{
				rs.close();
				stat.close();
				conn.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return ritorno;
	}
	public static Utente creaUtente(String nick,String pass){
		Utente ritorno=new Utente();
		String completaUtente="select * from Utenti where nick='"+nick+"' and pass='"+pass+"'";
		ResultSet rs=null;
		ritorno.setNick(nick);
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs=stat.executeQuery(completaUtente);
			while(rs.next()){
				ritorno.setCodice(rs.getInt(1));
				ritorno.setNome(rs.getString(2));
				ritorno.setCognome(rs.getString(3));
				//this.dataDiNascita=rs.getDate(4);
				ritorno.setIndirizo(rs.getString(5));
				ritorno.setPass(rs.getString(7));
			}
		}catch(SQLException e){
			e.printStackTrace();
		}catch(IOException ew){
			ew.printStackTrace();
		}
		finally{
			try{
				rs.close();
				stat.close();
				conn.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return ritorno;
	}

	public static Utente getUtenteTavolo(int idTav){
		Utente zx=null;
		ResultSet rs=null;
		int cod=0;
		String prendiUtente="select codiceU from TavoloUtente where idTavolo="+idTav;
		try {
			conn = getConnection();
			stat = conn.createStatement();
			rs = stat.executeQuery(prendiUtente);
			while(rs.next()){
				cod=Integer.parseInt(rs.getString(1));
			}
			zx=creaUtente(cod);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		finally{
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		System.out.println(zx);
		return zx;	
	}
	
	
	public boolean utenteGiaRegistrato(String ute){
		Utente tizio=new Utente();
		StringTokenizer st=new StringTokenizer(ute,"#");
		tizio.setCodice(Integer.parseInt(st.nextToken()));
		tizio.setCognome(st.nextToken());
		tizio.setIndirizo(st.nextToken());
		tizio.setNick(st.nextToken());
		tizio.setNome(st.nextToken());
		tizio.setPass(st.nextToken());
		ResultSet rs =null;
		boolean ce=false;
		Utente caio;
		
		
		try{
			conn = getConnection();
			stat = conn.createStatement();
			rs = stat.executeQuery("select * from Utenti where nome='"+tizio.getNome()+"' and cognome='"+tizio.getCognome()+"' and indirizzo='"+tizio.getIndirizzo()+"' and nick='"+tizio.getNick()+"'");
			while(rs.next()){
				String no=rs.getString(2);
				String c=rs.getString(3);
				String dN=(String)rs.getDate(4).toString();
				String i=rs.getString(5);
				String ni=rs.getString(6);
				
				caio=new Utente(no,c,ni,i,dN,"");
				if(caio.equals(tizio)){
					System.out.println("PRESENTE");
					ce=true;
				}
				else{
					System.out.println("NON E' possibile");
				}	
			}
		}catch(IOException d){
			d.printStackTrace();
		}catch(SQLException s){
			s.printStackTrace();
		}
		
		finally{
			try{
				rs.close();
				stat.close();
				conn.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return ce;
	}
	public boolean registraUtente(String ute){
		Utente tizio=new Utente();
		boolean eseguito=false;
		StringTokenizer st=new StringTokenizer(ute,"#");
		tizio.setCodice(Integer.parseInt(st.nextToken()));
		tizio.setCognome(st.nextToken());
		tizio.setIndirizo(st.nextToken());
		tizio.setNick(st.nextToken());
		tizio.setNome(st.nextToken());
		tizio.setPass(st.nextToken());
		String q="insert into Utenti (nome,cognome,dataNascita,indirizzo,nick,pass) values ('"+tizio.getNome()+"','"+tizio.getCognome()+"','"+tizio.getDataDiNascita()+"','"+tizio.getIndirizzo()+"','"+tizio.getNick()+"','"+tizio.getPass()+"')";
		try{
			conn=getConnection();
			stat=conn.createStatement();
			stat.executeUpdate(q);
			eseguito=true;
		}catch(IOException e){
			e.printStackTrace();
			eseguito=false;
		}
		catch(SQLException e){
			e.printStackTrace();
			eseguito=false;
		}
		finally{
			try{
				stat.close();
				conn.close();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
		return eseguito;
	}
	
	
	public boolean accediUtente(String n,String p){
		String connetti="select nick,pass from Utenti where nick='"+n+"' and pass='"+p+"'";
		ResultSet rs=null;
		try{
			conn=getConnection();
			stat=conn.createStatement();
			rs=stat.executeQuery(connetti);
			while(rs.next())
				return true;
			}catch (SQLException e){
				e.printStackTrace();
			}catch(IOException e){
				e.printStackTrace();
			}
		finally{
			try{
				rs.close();
				stat.close();
				conn.close();
			}catch(SQLException w){
				w.printStackTrace();
			}
		}
		return false;
	}
	
	
	public String evadiOrdine(int idTavolo) {
		String esito="DANNAZIONE";
		String CambiaStatoOrdine="update Ordinazione set statoOrdine='Evaso' where idTavolo='"+idTavolo+"'";
		try {
			Connection conn2 = getConnection();
			Statement stat2 = conn2.createStatement();
			stat2.executeUpdate(CambiaStatoOrdine);
			esito="OK";
		} catch (SQLException e) {
			e.printStackTrace();
			esito="DANNAZIONE";
		}catch(IOException d){
			d.printStackTrace();
		}
		/*
		catch(NullPointerException d){
			System.out.println("non ci sono ordini da evadere");
		}
		*/
		try{
			Connection conn1 = getConnection();
			Statement stat1 = conn1.createStatement();
			Connection conn3 = getConnection();
			Statement stat3 = conn3.createStatement();
			ResultSet rs=stat3.executeQuery("select codiceOrdinazione,codicePiatto from OrdinazionePiatto as i, Ordinazione as p  where i.codiceOrdinazione=p.codice and p.idTavolo='"+idTavolo+"'");
			while(rs.next()){
				int codiceOrdinazione=rs.getInt(1);
				int codicePiatto=rs.getInt(2);
				String cosaEliminare="delete from OrdinazionePiatto where codiceOrdinazione='"+codiceOrdinazione+"' and codicePiatto='"+codicePiatto+"'";
				stat1.executeUpdate(cosaEliminare);
				esito="OK";
			}
			stat1.close();
			rs.close();
		}catch(SQLException e){
			e.printStackTrace();
			esito="DANNAZIONE";
		}catch(IOException d){
			d.printStackTrace();
			esito="DANNAZIONE";
		}
		catch(NullPointerException d){
			System.out.println("non ci sono ordini da evadere");
		}
		return esito;
	}
	
	public String aggiornaOrdine(){
		ResultSet rs=null;
		String ritorno="";
		try{	
			conn=getConnection();
			stat=conn.createStatement();
			rs = stat.executeQuery("Select codicePiatto,idTavolo from Ordinazione as i , OrdinazionePiatto  as p where i.codice=p.CodiceOrdinazione and i.statoOrdine='Inevaso'");
			if(rs==null){
				return ritorno;
			}
			while(rs.next()){
				int codiceAlimento=rs.getInt(1);
				int idTav=rs.getInt(2);
				ritorno=ritorno+" "+codiceAlimento+" "+idTav;
			}
		}catch(SQLException s){
			s.printStackTrace();
			System.out.println("problema con il database Ordinetavolo");
		}catch(NullPointerException d){
			System.out.println("non ci sono ordini da evadere");
		}catch(IOException d){
			System.out.println("non ci sono ordini da evadere");
		}
		finally{
			if (rs!=null)
				try{
					rs.close();
				}catch(SQLException e){
					e.printStackTrace();
				}
		}
		return ritorno;
	}


	public static Connection getConnection() throws SQLException, IOException{  
		Properties props = new Properties();
		FileInputStream in = new FileInputStream("database.properties");
		props.load(in);
		in.close();

		String drivers = props.getProperty("jdbc.drivers");
		String url = props.getProperty("jdbc.url");
		String username = props.getProperty("jdbc.username");
		String password = props.getProperty("jdbc.password");

		if (drivers != null)
			System.setProperty("jdbc.drivers", drivers);

		return DriverManager.getConnection(url, username, password);
	}
}
